import type { ButtonsCallBackParams, PageInfo } from "plus-pro-components";
import { getList } from "@/api/apiJson";
import { defineAsyncComponent, nextTick, reactive, ref, shallowRef } from "vue";
import type { PagesProps } from "./types";
import { initPage } from "@/components/Crud/utils/init";

export function usePage() {
  /**
   * 动态组件参数
   */
  const moduleData = ref({
    params: {},
    from_config: {}
  });
  /**
   * 引用动态加载的组件实例
   */
  const dynamicComp = ref(null);
  /**
   * 动态加载组件
   */
  const dynamicComponent = shallowRef(null);
  /**
   * 搜索条件
   */
  let search = ref({});
  /**
   * 搜索条件Props传递
   */
  let searchProps = ref({});
  /**
   * 数据
   */
  let tableData = ref([]);
  /**
   * 页面初始化参数
   */
  let pages = ref<PagesProps>({
    id: 1,
    name: "本地演示",
    code: "demo",
    table_config: {
      columns: []
    },
    remark: "",
    get_url: "",
    business_code: "demo",
    params_json: [],
    operate_config: {},
    search_config: {
      columns: [],
      showNumber: 5
    },
    add_config: {
      columns: []
    },
    edit_config: {
      columns: []
    },
    toolbar_config: {
      columns: [
        {
          code: "add",
          name: "新增",
          type: "primary",
          size: "small"
        }
      ]
    }
  });
  /**
   * 请求参数
   */
  let params = ref({});
  /**
   * 分页配置
   */
  const pagination = reactive({
    pageInfo: {
      page: 1,
      pageSize: 10
    } as PageInfo,
    total: 0
  });

  /**
   * 初始化页面
   * @param pagesProps 页面code
   * @param searchPropsData 搜索条件
   */
  async function init(pagesProps: PagesProps, searchPropsData: object) {
    pages.value = pagesProps;
    await initPage(pages.value);
    params.value = Object.assign({}, ...pages.value.params_json);
    if (Object.keys(searchPropsData).length !== 0) {
      searchProps.value = {
        [pages.value.business_code]: {
          [searchPropsData["key"]]: searchPropsData["value"]
        }
      };
    }
    search.value = searchProps.value;
    await onSearchApiJson();
  }

  /**
   * 搜索组装
   * @param params 其他参数
   * @param search 搜索条件
   */
  function searchFit(params: object, search: object) {
    const newParams = { ...params };
    for (let key in search) {
      if (search.hasOwnProperty(key)) {
        // 如果两个对象都有这个key并且对应的值都是object，则递归合并
        if (
          newParams[key] &&
          typeof newParams[key] === "object" &&
          typeof search[key] === "object"
        ) {
          newParams[key] = searchFit(newParams[key], search[key]);
        } else {
          if (search[key] == undefined) {
            continue;
          }
          if (search[key].length !== 0) {
            // 否则直接覆盖
            newParams[key] = search[key];
          }
        }
      }
    }
    return newParams;
  }

  /**
   * 接口请求数据
   */
  async function onSearchApiJson() {
    //发送请求
    const response = await getList(
      searchFit(params.value, search.value),
      pagination.pageInfo.page - 1,
      pagination.pageInfo.pageSize
    );
    tableData.value = response["[]"];
    pagination.total = response.listTotal;
  }

  /**
   * 分页配置改变
   * @param _pageInfo
   */
  async function handlePaginationChange(_pageInfo: PageInfo) {
    pagination.pageInfo = _pageInfo;
    await onSearchApiJson();
  }

  /**
   * 搜索
   */
  async function handleSearch() {
    await onSearchApiJson();
  }

  /**
   * 搜索重置
   */
  async function handleReset() {
    search.value = searchProps.value;
    await onSearchApiJson();
  }

  /**
   * 操作按钮渲染组件
   * @param data
   */
  async function handleClickButton(data: ButtonsCallBackParams) {
    const code = data.buttonRow.code;
    dynamicComponent.value = defineAsyncComponent({
      loader: () => import(`../operate/${code}/index.vue`)
    });
    await nextTick();
    moduleData.value.params = data;
    moduleData.value.from_config = pages.value.edit_config;
  }

  /**
   * 工具栏按钮渲染组件
   * @param data
   */
  async function handleToolbarButton(data: any) {
    const code = data.code;
    dynamicComponent.value = defineAsyncComponent({
      loader: () => import(`../toolbar/${code}/index.vue`)
    });
    await nextTick();
    moduleData.value.params = {
      data: data,
      multipleSelection: multipleSelection.value
    };
    moduleData.value.from_config = pages.value.add_config;
  }

  /**
   * 多选参数
   */
  const multipleSelection = ref([]);

  /**
   * 多选事件
   * @param data
   */
  function handleSelectionChange(data: any) {
    multipleSelection.value = data;
  }

  return {
    handleToolbarButton,
    handleSelectionChange,
    moduleData,
    dynamicComp,
    dynamicComponent,
    handleSearch,
    handleReset,
    search,
    pages,
    init,
    tableData,
    pagination,
    handlePaginationChange,
    handleClickButton
  };
}
